package json

import (
	"codejy/analysis"
	"codejy/assignmentstrategy"
	"codejy/store"
	"codejy/structdef"
	"codejy/typedefault"
	"codejy/typedefault/container"
	"codejy/utils"
	"strings"
)

// key 实例地址,value 值

type Json struct {
	Addr        string
	ThreadStore *structdef.ThreadStore
}

func (f *Json) CreateTypeDefault(addr string, threadStore *structdef.ThreadStore, parameter ...string) {
	fUtil := &Json{
		Addr:        addr,
		ThreadStore: threadStore,
	}
	store.AddTypeDefaultInstanceStore(threadStore, f.GetTypeName(), addr, fUtil)
}
func (f *Json) GetData() interface{} {
	return nil
}

func (a *Json) ToStr() string {
	return ""
}
func (a *Json) ParameterProcessing(parameter []string) []string {
	//排除前后""
	for i := range parameter {
		s := parameter[i]
		if strings.HasPrefix(s, "\"") && strings.HasSuffix(s, "\"") {
			s = s[1 : len(s)-1]
			parameter[i] = s
		}
	}
	return parameter
}

// 将json转换为map
func (a *Json) JsonToMap(json string) string {
	object := utils.IsValidJSONObject(json)
	if !object {
		panic("不是json对象,请检查格式")
	}
	return a.jsonToMap(json)
}
func (a *Json) jsonToMap(json string) string {
	jsonObj := utils.JsonToMap(json)
	//遍历value,判断value是否是json对象
	for key, value := range jsonObj {
		a.jsonSwitchListMap(jsonObj, key, value)
	}
	toMap := container.MapToMap(jsonObj, a.ThreadStore)
	return toMap
}

// 将json转换为list
func (a *Json) JsonToList(json string) string {
	object := utils.IsValidJSONArray(json)
	if !object {
		panic("不是json数组,请检查格式")
	}
	return a.jsonToList(json)
}

func (a *Json) jsonToList(json string) string {
	var jsonObj []string
	jsonArray := utils.JsonToSliceMap(json)
	for i := range jsonArray {
		m := jsonArray[i]
		//遍历value,判断value是否是json对象
		for key, value := range m {
			a.jsonSwitchListMap(m, key, value)
		}
		toMap := container.MapToMap(m, a.ThreadStore)
		jsonObj = append(jsonObj, toMap)
	}
	//转换为list实例
	return container.SliceToList(jsonObj, a.ThreadStore)
}

// json转换为map,list
func (a *Json) jsonSwitchListMap(m map[string]string, key, value string) string {
	object := utils.IsValidJSONObject(value)
	if object {
		m[key] = a.jsonToMap(value)
	}
	//判断value是否是json数组
	array := utils.IsValidJSONArray(value)
	if array {
		m[key] = a.jsonToList(value)
	}
	return m[key]
}

// 将map转换为json
func (a *Json) MapToJson(map1 string) string {
	value, b := typedefault.GetTypeDefaultValue[map[string]string](a.ThreadStore, "Map", map1)
	if b {
		var jsonStr = "{"
		for k, v := range value {
			key := "\"" + k + "\""
			value1 := a.listMapSwitchJson(v)
			jsonStr = jsonStr + key + ":" + value1 + ","
		}
		jsonStr = jsonStr[0:len(jsonStr)-1] + "}"
		return jsonStr
	}
	panic("找Map实例,map转json失败")
}

// 将json转为自定义类型,要求json的key和自定义类型的字段名一致(区分大小写)
func (a *Json) JsonToType(json string, typeName string) string {
	//判断是否是json对象
	object := utils.IsValidJSONObject(json)
	if !object {
		panic("不是json对象,请检查格式")
	}
	//将json转换为map
	value := utils.JsonToMap(json)
	for k, v := range value {
		value1 := a.jsonSwitchListMap(value, k, v)
		value[k] = value1
	}
	//创建实例
	addr := assignmentstrategy.CreateInstanceMapNotInit(a.ThreadStore, typeName, value)
	return addr
}

// 将List转换为json
func (a *Json) ListToJson(list string) string {
	value, b := typedefault.GetTypeDefaultValue[[]string](a.ThreadStore, "List", list)
	if b {
		var listJson string
		listJson = "["
		for i := range value {
			switchListMap := a.listMapSwitchJson(value[i])
			listJson = listJson + switchListMap + ","
		}
		listJson = listJson[0:len(listJson)-1] + "]"
		return listJson
	}
	return ""
}

// List和Map,自定义类型,转换为json
func (a *Json) listMapSwitchJson(str string) string {
	//判断是否是实例
	address := analysis.IsInstanceAddress(str)
	if !address { //不是实例,直接返回
		return str
	}
	//如果不是自定义类型,判断是否是List或者Map
	pd, typeName := store.GetTypeDefaultInstanceInversionStore(a.ThreadStore, str)
	if pd { //是默认类型
		switch typeName {
		case "List":
			return a.ListToJson(str)
		case "Map":
			return a.MapToJson(str)
		}
	}
	//如果不是默认类型,就将自定义类型转换为json
	return a.TypeToJson(str)
}

// 将自定义类型转换为json
func (a *Json) TypeToJson(str string) string {
	prop, b := store.GetInstanceProp(a.ThreadStore, str)
	if !b {
		panic("不存在" + str + "实例")
	}
	var jsonStr = "{"
	for k, v := range prop {
		key := "\"" + k + "\""
		value := a.listMapSwitchJson(v.Value)
		//排除@TYPENAME@和@TYPEFILEPATH@
		if k == "@TYPENAME@" || k == "@TYPEFILEPATH@" {
			continue
		}
		//去掉双引号
		if strings.HasPrefix(value, "\"") && strings.HasSuffix(value, "\"") {
			value = value[1 : len(value)-1]
		}
		jsonStr = jsonStr + key + ":" + analysis.AddDoubleQuotationMarks(value) + ","

	}
	jsonStr = jsonStr[0:len(jsonStr)-1] + "}"
	return jsonStr
}

func (f *Json) GetDef() string {
	return `
		@CodeManual(def="Json.xxx",des="Json操作工具类")
		type share Json{
			def init{
				core&CreateTypeDefault()
			}
			@CodeManual(def="Json.toMap(jsonStr)",des="将json字符串对象转换为map")
			def toMap{
				to core&JsonToMap($1)
			}
			@CodeManual(def="Json.toList(jsonStr)",des="将json字符串对象转换为List")
			def toList{
				to core&JsonToList($1)
			}

			@CodeManual(def="Json.toType(json,typeName)",des="将json字符串对象转换为自定义类型,要求json的key和自定义类型的字段名一致(区分大小写)")
			def toType{
				to core&JsonToType($1,$2)
			}

			def mapTo{
				to core&MapToJson($1)
			}
			def listTo{
				to core&ListToJson($1)
			}
			def typeTo{
				to core&TypeToJson($1)
			}
		}
	`
}

func init() {
	typedefault.RegisterTypeDefault(&Json{})
}
func (f *Json) GetTypeName() string {
	return "Json"
}
